#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <net/ethernet.h>
#include <netinet/ether.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <arpa/inet.h>
#include <iostream>
#include <linux/if_ether.h>
#include <sys/socket.h>
#include <netpacket/packet.h>
#include <net/ethernet.h>
#include <net/if.h>
#include <stropts.h>
#include <sys/ioctl.h>
#include "definitions.hpp"

using namespace std;

#define SIZE_ETHERNET 14


void* rdwrif_thread_func(void* val){


	int sock_eth;

	 if ((sock_eth = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0) {
        perror("socket-eth-rdwrif2");
        exit(1);
    }


	   struct sockaddr_ll sll;
	   struct ifreq ifr;

	   bzero(&sll, sizeof(sll));
	   bzero(&ifr, sizeof(ifr));
   
       int *i  = (int*) val;
	   list<string>::iterator it;
	   cout<< *i << "in thread ";
	   it = interface_list.begin();
	   for(int k=1; k < (*i); k++){
		it++;
	   }

	   char* dev = (char *)(*it).c_str();
	   string macadd = ipadd_map[*it];
	   /* First Get the Interface Index  */
	   strncpy((char *)ifr.ifr_name, dev, IFNAMSIZ);
	   if((ioctl(sock_eth, SIOCGIFINDEX, &ifr)) == -1)
	   {
	   printf("Error getting Interface index !\n");
	   exit(-1);
	   }

	   /* Bind our raw socket to this interface */

	   sll.sll_family = AF_PACKET;
	   sll.sll_ifindex = ifr.ifr_ifindex;
	  // sll.sll_protocol = htons(ETH_P_IP);

	   if((bind(sock_eth, (struct sockaddr *)&sll, sizeof(sll)))== -1)
	   {
	   perror("Error binding raw socket to interface\n");
	   exit(-1);
       }

   list<unsigned char*> tmp_packet_q;
   if(*i == 1){
     tmp_packet_q = packet_q_i1;
   } else if (*i == 2)
     {
      tmp_packet_q = packet_q_i2;
   } else if (*i == 3)
     {
	   tmp_packet_q = packet_q_i3;
   } else 
	 {
	   tmp_packet_q = packet_q_i4;
   }
  
 while(1){
	 if(tmp_packet_q.size() <= 0){
	 usleep(100);
		 continue;
	 }
  unsigned char* buf = tmp_packet_q.front();
  tmp_packet_q.pop_front();


  // Read the raw message // Begin

   struct ethhdr *eth_hdr;

	eth_hdr = (struct ethhdr *)buf;
    memcpy(eth_hdr->h_source, eth_hdr->h_dest, ETH_ALEN);
	memcpy(eth_hdr->h_dest, (void *)(ether_aton(macadd.c_str())), ETH_ALEN);

  // Read the raw message // End


// Write into a raw socket
    cout<<"writing into dev" <<dev<<endl;

	int r;

     r = write(sock_eth, buf, 66);
     if(r <0) {
		 perror("sendto-if1");
	 }
	 cout<<"Bytes Sent on if1 R "<<r<<endl;


 //free(buf);

}// while(1)
}//rdwr function



